"""
Case Type   : 共享存储-系统内部工具-dsscmd
Case Name   : dsscmd工具将源文件复制到目标文件
Create At   : 2023/4/14
Owner       : opentestcase019
Description :
    1.将源文件复制到目标文件，指定-s src_file和-d dest_file参数为正常值
    2.将源文件复制到目标文件，指定-s src_file参数为不存在的文件名
    3.将源文件复制到目标文件，指定-s src_file参数为命名不规范的文件名
    4.将源文件复制到目标文件，指定dest_file参数为纯数字和纯字母
    5.将源文件复制到目标文件，指定dest_file参数为命名不规范的文件名
    6.将源文件复制到目标文件，指定正确的-U UDS:socket_domain参数
    7.将源文件复制到目标文件，指定错误的-U UDS:socket_domain参数
    8.将源文件复制到目标文件，指定权限不足的socket_domain
    9.在备机执行将源文件复制到目标文件
    10.在集群停止的情况下执行
    11.在dss关闭的情况下执行
Expect      :
    1.复制成功
    2.合理报错
    3.合理报错
    4.复制成功
    5.合理报错
    6.复制成功
    7.合理报错Failed to get uds connection.
    8.合理报错Failed to get uds connection.
    9.复制成功
    10.合理报错
    11.合理报错
History     :
"""
import os
import time
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class ShareStorageTool(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.standby_node = Node('Standby1DbUser')
        self.common = Common()
        self.constant = Constant()
        self.file_name_1 = "file_dsscmd_0022_1"
        self.file_name_2 = "file_dsscmd_0022_2"
        self.file_name_3 = "file_dsscmd_0022_3"
        self.file_name_4 = "file_dsscmd_0022_4"
        self.file_name_5 = "file_dsscmd_0022_5"
        self.file_name_6 = "file_dsscmd_0022_6"
        self.file_name_not_exists = "file_dsscmd_0022_not_exists"
        self.file_name_64chars = \
            "file_dsscmd_0022_file_dsscmd_0022_file_dsscmd_0022_file_dsscmd_0"
        self.file_name_63chars = \
            "file_dsscmd_0022_file_dsscmd_0022_file_dsscmd_0022_file_dsscmd_"
        self.file_name_numbers = "0022"
        self.file_name_letters = "filedsscmd"
        self.logger.info("-----获取卷组名-----")
        execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd lsvg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn("Succeed to display lsvg info.", execute_msg, "获取卷组名失败")
        self.vgname_1 = execute_msg.splitlines()[1].split()[0].strip()
        self.vgname_2 = execute_msg.splitlines()[2].split()[0].strip()
        self.logger.info(self.vgname_1)
        self.logger.info(self.vgname_2)
        self.srcpath_1 = os.path.join(self.vgname_1, self.file_name_1)
        self.destpath_1 = os.path.join(self.vgname_2, self.file_name_1)
        self.destpath_2 = os.path.join(self.vgname_2, self.file_name_2)
        self.destpath_3 = os.path.join(self.vgname_2, self.file_name_3)
        self.destpath_4 = os.path.join(self.vgname_2, self.file_name_4)
        self.destpath_5 = os.path.join(self.vgname_2, self.file_name_5)
        self.destpath_6 = os.path.join(self.vgname_2, self.file_name_6)
        self.destpath_63chars = os.path.join(self.vgname_2,
                                             self.file_name_63chars)
        self.srcpath_not_exists = os.path.join(self.vgname_1,
                                               self.file_name_not_exists)
        self.srcpath_64chars = os.path.join(self.vgname_1,
                                            self.file_name_64chars)
        self.destpath_64chars = os.path.join(self.vgname_2,
                                             self.file_name_64chars)
        self.destpath_numbers = os.path.join(self.vgname_2,
                                             self.file_name_numbers)
        self.destpath_letters = os.path.join(self.vgname_2,
                                             self.file_name_letters)

    def test_sharestorage_tool(self):
        step1 = "-----step1:将源文件复制到目标文件，指定-s src_file" \
                "和-d dest_file参数为正常值;expect:复制成功-----"
        self.logger.info(step1)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.srcpath_1};" \
            f"dsscmd touch -p +{self.srcpath_1}$#;" \
            f"dsscmd cp -s +{self.srcpath_1} -d +{self.destpath_1};" \
            f"dsscmd cp -s +{self.srcpath_1}$1 -d +{self.destpath_2};" \
            f"dsscmd cp -s +{self.srcpath_1}$q -d +{self.destpath_3};" \
            f"dsscmd cp -s +{self.srcpath_1}$# -d +{self.destpath_4};" \
            f"dsscmd cp -s +{self.srcpath_1} -d +{self.destpath_63chars};"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(2, execute_msg.count("Succeed to create file"),
                          "执行失败" + step1)
        self.assertEquals(5, execute_msg.count("Succeed to copy file"),
                          "执行失败" + step1)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd ls -p +{self.vgname_2}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.file_name_1, execute_msg, "执行失败" + step1)
        self.assertIn(self.file_name_2, execute_msg, "执行失败" + step1)
        self.assertIn(self.file_name_3, execute_msg, "执行失败" + step1)
        self.assertIn(self.file_name_4, execute_msg, "执行失败" + step1)
        self.assertIn(self.file_name_63chars, execute_msg, "执行失败" + step1)

        step2 = "-----step2:将源文件复制到目标文件，指定-s src_file参数" \
                "为不存在的文件名;expect:合理报错-----"
        self.logger.info(step2)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd cp -s +{self.srcpath_not_exists} -d +{self.destpath_1}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"The file {self.file_name_not_exists} of "
                      f"+{self.srcpath_not_exists} does not exist",
                      execute_msg, "执行失败" + step2)

        step3 = "-----step3:将源文件复制到目标文件，指定-s src_file参数" \
                "为命名不规范的文件名;expect:合理报错-----"
        self.logger.info(step3)
        cmd_list = [f'+{self.srcpath_1}%*#', f'+{self.srcpath_64chars}',
                    f'+{self.srcpath_1}文件', f'+{self.srcpath_1}&%',
                    f'{self.srcpath_1}']
        for cmd in cmd_list:
            execute_cmd = f"source {macro.DB_ENV_PATH};" \
                f"dsscmd cp -s {cmd} -d +{self.destpath_1}"
            self.logger.info(execute_cmd)
            execute_msg = self.common.get_sh_result(self.primary_node,
                                                    execute_cmd)
            if cmd == cmd_list[1]:
                self.assertIn(f"Path  decode error name length should less "
                              f"than 64", execute_msg, "执行失败" + step3)
            elif cmd == cmd_list[3]:
                self.assertIn("args [-d|--dest_file] needs input value.",
                              execute_msg, "执行失败" + step3)
            elif cmd == cmd_list[-1]:
                self.assertIn("The format of srcpath or destpath is wrong.",
                              execute_msg, "执行失败" + step3)
            else:
                self.assertIn("decode error , path should be "
                              "[0~9,a~z,A~Z,-,_,/,.].",
                              execute_msg, "执行失败" + step3)

        step4 = "-----step4:将源文件复制到目标文件，指定dest_file参数" \
                "为纯数字和纯字母;expect:复制成功-----"
        self.logger.info(step4)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd cp -s +{self.srcpath_1} -d +{self.destpath_numbers};" \
            f"dsscmd cp -s +{self.srcpath_1} -d +{self.destpath_letters}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(2, execute_msg.count("Succeed to copy file"),
                          "执行失败" + step4)

        step5 = "-----step5:将源文件复制到目标文件，指定dest_file参数" \
                "为命名不规范的文件名;expect:合理报错-----"
        self.logger.info(step5)
        cmd_list = [f'+{self.destpath_1}%$#&*', f'+{self.destpath_64chars}',
                    f'+{self.destpath_1}', f'+{self.destpath_1}文件',
                    f'{self.destpath_1}']
        for cmd in cmd_list:
            execute_cmd = f"source {macro.DB_ENV_PATH};" \
                f"dsscmd cp -s {self.srcpath_1} -d {cmd}"
            self.logger.info(execute_cmd)
            execute_msg = self.common.get_sh_result(self.primary_node,
                                                    execute_cmd)
            if cmd == cmd_list[0] or cmd == cmd_list[3]:
                self.assertIn("decode error , path should be "
                              "[0~9,a~z,A~Z,-,_,/,.].",
                              execute_msg, "执行失败" + step5)
            else:
                self.assertIn("The format of srcpath or destpath is wrong.",
                              execute_msg, "执行失败" + step5)

        step6 = "-----step6:将源文件复制到目标文件，指定正确的" \
                "-U UDS:socket_domain参数;expect:复制成功-----"
        self.logger.info(step6)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd cp -s +{self.srcpath_1} -d +{self.destpath_5} " \
            f"-U {macro.UDS_PATH}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to copy file from srcpath +{self.srcpath_1} "
                      f"to destpath +{self.destpath_5}.",
                      execute_msg, "执行失败" + step6)

        step7 = "-----step7:将源文件复制到目标文件，指定错误的-U UDS:socket_domain参数;" \
                "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step7)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd cp -s +{self.srcpath_1} -d +{self.destpath_5} " \
            f"-U {macro.UDS_PATH}.cfg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step7)

        step8 = "-----step8:将源文件复制到目标文件，指定权限不足的socket_domain;" \
                "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step8)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"chmod 000 {macro.UDS_PATH[4::]};" \
            f"dsscmd cp -s +{self.srcpath_1} -d +{self.destpath_5} " \
            f"-U {macro.UDS_PATH};" \
            f"chmod 600 {macro.UDS_PATH[4::]}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step8)

        step9 = "-----step9:在备机执行将源文件复制到目标文件;expect:复制成功-----"
        self.logger.info(step9)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd cp -s +{self.srcpath_1} -d +{self.destpath_6} " \
            f"-U {macro.UDS_PATH};"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.standby_node, execute_cmd)
        self.assertIn(f"Succeed to copy file from srcpath +{self.srcpath_1} "
                      f"to destpath +{self.destpath_6}.",
                      execute_msg, "执行失败" + step9)

        step10 = "-----step10:在集群停止的情况下执行;expect:合理报错-----"
        self.logger.info(step10)
        stop_msg = Primary_SH.exec_cm_ctl(mode='stop')
        self.logger.info(stop_msg)
        self.assertIn(self.constant.cm_stop_success_msg,
                      stop_msg, '执行失败' + step10)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd cp -s +{self.srcpath_1} -d +{self.destpath_6}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.standby_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step10)
        start_msg = Primary_SH.exec_cm_ctl(mode='start')
        self.logger.info(start_msg)
        self.assertIn(self.constant.cm_start_success_msg,
                      start_msg, '启动集群失败')
        time.sleep(30)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, "执行失败" + step10)

        step11 = "-----step11:在dss关闭的情况下执行;expect:合理报错-----"
        self.logger.info(step11)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd stopdss;" \
            f"sleep 2;" \
            f"dsscmd cp -s +{self.srcpath_1} -d +{self.destpath_6}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step11)

    def tearDown(self):
        self.logger.info("-----环境清理-----")
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        if "cluster_state   : Normal" not in status:
            start_msg = Primary_SH.exec_cm_ctl(mode='start')
            self.logger.info(start_msg)
        time.sleep(30)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd rm -p +{self.srcpath_1};" \
            f"dsscmd rm -p +{self.srcpath_1}$#;" \
            f"dsscmd rm -p +{self.destpath_1};" \
            f"dsscmd rm -p +{self.destpath_2};" \
            f"dsscmd rm -p +{self.destpath_3};" \
            f"dsscmd rm -p +{self.destpath_4};" \
            f"dsscmd rm -p +{self.destpath_5};" \
            f"dsscmd rm -p +{self.destpath_6};" \
            f"dsscmd rm -p +{self.destpath_63chars};" \
            f"dsscmd rm -p +{self.destpath_numbers};" \
            f"dsscmd rm -p +{self.destpath_letters};"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn('cluster_state   : Normal', status, '恢复环境失败')
        self.assertEquals(11, execute_msg.count("Succeed to remove device"),
                          "环境清理失败")
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
